<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
      //实现一个new
    // 它创建了一个全新的对象。
    // 它会被执行 [[Prototype]]（也就是 __proto__）链接。
    // 它使 this指向新创建的对象。。
    // 通过 new创建的每个对象将最终被 [[Prototype]]链接到这个函数的 prototype对象上。
    // 如果函数没有返回对象类型 Object(包含 Functoin,Array,Date,RegExg,Error)，那么 new表达式中的函数调用将返回该对象引用。
      function newF() {
        // 创建一个新的对象
        let obj = {};
        // 取出第一个参数，该参数就是我们将会传入的构造函数，比如在调用new(P)的时候，Constructor就是P本身
        // arguments会被shift去除第一个参数，剩余的就是构造器P的参数
        let Constructor = [].shift.call(arguments);
        if(typeof Constructor !== "function"){
          throw  "first params must be function"
        }
        // 将obj的原型指向构造函数，此时obj可以访问构造函数原型中的属性
        obj.__proto__ = Constructor.prototype;
        // 改变构造函数的this的指向，使其指向obj， 此时obj也可以访问构造函数中的属性了
       let result =Constructor.apply(obj, arguments);
        // 确保 new 出来的是个对象 返回的值是什么就return什么
        return typeof result === 'object' ? result : obj
      }

      function A(name,a,b){
        this.name = name;
        this.a = a;
        console.log(this.name)
        console.log(a+b)
      }

      console.log(newF(A,'小米',1,2))







</script>
</body>
</html>
